{ "cells": [ { "cell_type": "markdown", "id": "cf32eb3c-ae3b-4ee0-ad24-e84cfc2ee175", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "# Calculating Quantities\n", "\n", "There are various built-in functions to calculate quantities, not limited to:\n", "\n", "- {func}`~quimb.calc.fidelity`\n", "- {func}`~quimb.calc.purify`\n", "- {func}`~quimb.calc.dephase`\n", "- {func}`~quimb.calc.kraus_op`\n", "- {func}`~quimb.calc.projector`\n", "- {func}`~quimb.calc.measure`\n", "- {func}`~quimb.calc.cprint`\n", "- {func}`~quimb.calc.entropy`\n", "- {func}`~quimb.calc.mutinf`\n", "- {func}`~quimb.calc.mutinf_subsys`\n", "- {func}`~quimb.calc.schmidt_gap`\n", "- {func}`~quimb.calc.tr_sqrt`\n", "- {func}`~quimb.calc.partial_transpose`\n", "- {func}`~quimb.calc.logneg`\n", "- {func}`~quimb.calc.logneg_subsys`\n", "- {func}`~quimb.calc.negativity`\n", "- {func}`~quimb.calc.concurrence`\n", "- {func}`~quimb.calc.one_way_classical_information`\n", "- {func}`~quimb.calc.quantum_discord`\n", "- {func}`~quimb.calc.trace_distance`\n", "- {func}`~quimb.calc.decomp`\n", "- {func}`~quimb.calc.correlation`\n", "- {func}`~quimb.calc.pauli_correlations`\n", "- {func}`~quimb.calc.ent_cross_matrix`\n", "- {func}`~quimb.calc.is_degenerate`\n", "- {func}`~quimb.calc.is_eigenvector`\n", "- {func}`~quimb.calc.page_entropy`\n", "- {func}`~quimb.calc.heisenberg_energy`\n", "\n", "## Approximate Spectral Functions\n", "\n", "The module {py:mod}`~quimb.linalg.approx_spectral`, contains a Lanczos method for estimating any quantities of the form `tr(fn(A))`. Where `A` is any operator that implements a dot product with a vector. For example, estimating the trace of the sqrt of a matrix would naievly require diagonalising it:" ] }, { "cell_type": "code", "execution_count": 1, "id": "f7e97ca6-40b0-4f82-a22b-0e911c14c076", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "54.32566715771646" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import quimb as qu\n", "\n", "rho = qu.rand_rho(2**12)\n", "rho_el = qu.eigvalsh(rho)\n", "sum(rho_el**0.5)" ] }, { "cell_type": "code", "execution_count": 2, "id": "5393cf7e-c28a-4704-9515-9de49152e2ff", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "54.45773513531054" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "qu.tr_sqrt_approx(rho)" ] }, { "cell_type": "markdown", "id": "30600c0b-485a-4b74-8231-5274faab41ba", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "Diagonalization has a cost of `O(n^3)`, which is essentially reduced\n", "to `O(k * n^2)` for this stochastic method. For a general function\n", "{func}`~quimb.linalg.approx_spectral.approx_spectral_function` can be used.\n", "\n", "However, the real advantage occurs when the full matrix does not need to be fully represented, e.g. in the case of 'partial trace states'. One can then calculate quantities for subsystems that would not be possible to explicitly represent.\n", "\n", "For example, the partial trace, followed by partial transpose, followed by vector multiplication can be 'lazily' evaluated as a tensor contraction (see {py:func}`~quimb.linalg.approx_spectral.lazy_ptr_ppt_dot`). In this way the logarithmic negativity of subsytems can be efficiently calculated:" ] }, { "cell_type": "code", "execution_count": 3, "id": "a7256fd6-29e4-477b-9763-538184dad92d", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5.7437225898123465" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "psi = qu.rand_ket(2**20)\n", "dims = [2**8, 2**4, 2**8]\n", "qu.logneg_subsys_approx(psi, dims, sysa=0, sysb=2)" ] }, { "cell_type": "markdown", "id": "bb7e3ade-3cd6-4718-a552-13dcf0c172be", "metadata": {}, "source": [ "To inspect the process you can supply an `info` dict, and optionally also have the trials plotted like so:" ] }, { "cell_type": "code", "execution_count": 4, "id": "bd82a29b-1ba5-4e57-8e99-f6b439c1396a", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "1.217(12)e+11: 40%|############################4 | 411/1024 [00:34<00:50, 12.03it/s]\n" ] }, { "data": { "image/svg+xml": [ "" ], "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "%config InlineBackend.figure_formats = ['svg']\n", "\n", "# estimate a 2D partition function\n", "beta = 2.0\n", "H = qu.ham_heis_2D(4, 4, bz=1.7, sparse=True)\n", "\n", "# if plot=False, the desired keys should be filled before supplying info\n", "info = {}\n", "\n", "Z = qu.approx_spectral_function(\n", " H,\n", " f=lambda x: qu.exp(-beta * x),\n", " tol=1e-2,\n", " info=info,\n", " progbar=True,\n", " plot=True,\n", ")" ] }, { "cell_type": "code", "execution_count": 5, "id": "984af762-97ad-4fc6-9430-8a4c5750e41f", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "dict_keys(['estimate', 'error', 'samples', 'estimates_raw', 'estimates_window', 'estimates_fit', 'estimates', 'fig', 'axs'])" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "info.keys()" ] } ], "metadata": { "celltoolbar": "Raw Cell Format", "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3" }, "vscode": { "interpreter": { "hash": "39c10650315d977fb13868ea1402e99f3e10e9885c2c202e692ae90b8995050d" } } }, "nbformat": 4, "nbformat_minor": 4 }